﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.Data;
using Prodma.DataAccess.Database;
using Prodma.DataAccess.Interfaces.Models;
using Prodma.DataAccess.Models.ViewModels;
using Prodma.DataAccess.Repositories;
using Prodma.DataAccess.Helper.Enumerators;
using System.Configuration;

namespace Prodma.DataAccess.DataService
{
    public class BannerService : IBannerRepository
    {

        private DataContext context = new DataContext();

        #region IBannerRepository Members

        public IList<int> GetAreaList()
        {
            DataContext context = new DataContext();
            using (context)
            {
                var list = (from banner in context.tb_Banner
                            group banner by banner.tb_Area.Id into area
                            select area.Key).ToList();

                return list;
            }
        }
        #endregion

        #region IRecordOperation<tb_Banner,BannerVm> Members

        public IList<BannerVm> GetList()
        {
            DataContext context = new DataContext();
            using (context)
            {
                var list = (from banner in context.tb_Banner
                            join order in context.tb_BannerOrder
                                on banner.Id equals order.Banner
                            select new BannerVm()
                            {
                                Id = banner.Id,
                                Name = banner.Name,
                                Banner = banner.Banner,
                                Area = new AreaVm() { Id = banner.tb_Area.Id, Name = banner.tb_Area.Name },
                                Order = new BannerOrderVm() { OrderNo = order.OrderNo },
                                State = new StateVm() { Id = banner.tb_State.Id, Name = banner.tb_State.Name }
                            }).OrderByDescending(x => x.Order).ToList();

                return list;
            }
        }
        public void New(tb_Banner entity)
        {
            DataContext context = new DataContext();
            using (context)
            {
                context.AddTotb_Banner(entity);
                context.SaveChanges();
            }
        }
        public BannerVm Edit(int id)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var edit = (from banner in context.tb_Banner
                            where banner.Id == id
                            select new BannerVm()
                            {
                                Id = banner.Id,
                                Name = banner.Name,
                                Banner = banner.Banner,
                                Area = new AreaVm() { Id = banner.tb_Area.Id, Name = banner.tb_Area.Name },
                                State = new StateVm() { Id = banner.tb_State.Id, Name = banner.tb_State.Name }
                            }).FirstOrDefault();
                return edit;
            }
        }
        public void Update(int id, tb_Banner entity)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var edit = (from banner in context.tb_Banner
                            where banner.Id == id
                            select banner).FirstOrDefault();

                edit.Name = entity.Name;
                edit.Banner = entity.Banner;
                edit.tb_AreaReference.EntityKey = entity.tb_AreaReference.EntityKey;
                edit.tb_StateReference.EntityKey = entity.tb_StateReference.EntityKey;

                context.SaveChanges();
            }
        }
        public void Delete(int id)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var delete = (from banner in context.tb_Banner
                              where banner.Id == id
                              select banner).FirstOrDefault();

                context.DeleteObject(delete);
                context.SaveChanges();
            }
        }
        #endregion

        #region IFindOperation<BannerVm> Members

        public IList<BannerVm> GetList(Dictionary<string, string> find)
        {
            string findName = find["name"];
            DataContext context = new DataContext();
            using (context)
            {
                var list = (from banner in context.tb_Banner
                            join order in context.tb_BannerOrder
                                on banner.Id equals order.Banner
                            where banner.Name.StartsWith(findName)
                            select new BannerVm()
                            {
                                Id = banner.Id,
                                Name = banner.Name,
                                Banner = banner.Banner,
                                Area = new AreaVm() { Id = banner.tb_Area.Id, Name = banner.tb_Area.Name },
                                Order = new BannerOrderVm() { OrderNo = order.OrderNo },
                                State = new StateVm() { Id = banner.tb_State.Id, Name = banner.tb_State.Name }
                            }).OrderByDescending(x => x.Order).ToList();

                return list;
            }
        }
        #endregion

        #region IOrderOperation<BannerOrderVm> Members

        public void OrderUp(int id, BannerOrderVm viewModel)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var currentOrder = (from order in context.tb_BannerOrder
                                    where order.Banner == viewModel.Banner &&
                                          order.tb_Area.Id == viewModel.Area &&
                                          order.OrderNo == viewModel.OrderNo
                                    select order).FirstOrDefault();

                var nextOrder = (from order in context.tb_BannerOrder
                                 where order.OrderNo > viewModel.OrderNo &&
                                       order.tb_Area.Id == viewModel.Area
                                 select order).OrderBy(x => x.OrderNo).FirstOrDefault();

                if (nextOrder != null)
                {
                    nextOrder.OrderNo--;
                    currentOrder.OrderNo++;
                }

                context.SaveChanges();
            }
        }
        public void OrderDown(int id, BannerOrderVm viewModel)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var currentOrder = (from order in context.tb_BannerOrder
                                    where order.Banner == viewModel.Banner &&
                                          order.tb_Area.Id == viewModel.Area &&
                                          order.OrderNo == viewModel.OrderNo
                                    select order).FirstOrDefault();

                var previousOrder = (from order in context.tb_BannerOrder
                                     where order.OrderNo < viewModel.OrderNo &&
                                           order.tb_Area.Id == viewModel.Area
                                     select order).OrderByDescending(x => x.OrderNo).FirstOrDefault();

                if (previousOrder != null)
                {
                    previousOrder.OrderNo++;
                    currentOrder.OrderNo--;
                }

                context.SaveChanges();
            }
        }
        public void SetOrder(int id, BannerOrderVm viewModel)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var lastOrder = (from order in context.tb_BannerOrder
                                 where order.tb_Area.Id == viewModel.Area
                                 select order).OrderByDescending(x => x.OrderNo).Take(1).FirstOrDefault();

                if (viewModel.SetOrderNo > lastOrder.OrderNo || viewModel.SetOrderNo <= 0)
                {
                    return;
                }

                var currentOrder = (from order in context.tb_BannerOrder
                                    where order.Banner == viewModel.Banner &&
                                          order.tb_Area.Id == viewModel.Area &&
                                          order.OrderNo == viewModel.OrderNo
                                    select order).FirstOrDefault();

                int setOrderNo = (lastOrder.OrderNo - viewModel.SetOrderNo) + 1;
                int fark = setOrderNo - currentOrder.OrderNo;
                int oldCurrentOrder = currentOrder.OrderNo;
                currentOrder.OrderNo = setOrderNo;

                if (fark > 0)
                {
                    var nextOrder = (from order in context.tb_BannerOrder
                                     where order.OrderNo > oldCurrentOrder &&
                                           order.OrderNo <= setOrderNo &&
                                           order.tb_Area.Id == viewModel.Area
                                     select order).OrderBy(x => x.OrderNo).ToList();

                    foreach (tb_BannerOrder m in nextOrder)
                    {
                        m.OrderNo--;
                        context.SaveChanges();
                    }
                }
                else if (fark <= 0)
                {
                    var previousOrder = (from order in context.tb_BannerOrder
                                         where order.OrderNo < oldCurrentOrder &&
                                               order.OrderNo >= setOrderNo &&
                                               order.tb_Area.Id == viewModel.Area
                                         select order).OrderBy(x => x.OrderNo).ToList();

                    foreach (tb_BannerOrder m in previousOrder)
                    {
                        m.OrderNo++;
                        context.SaveChanges();
                    }
                }

                context.SaveChanges();
            }
        }
        #endregion

        #region IParentRelationshipOperation Members

        public IList<int> GetCounts()
        {
            DataContext context = new DataContext();
            using (context)
            {
                var countList = (from banner in context.tb_Banner
                                 group banner by banner.tb_Area.Id into area
                                 select area.Count()).ToList();

                return countList;
            }
        }
        public IList<int> GetCounts(string find)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var countList = (from banner in context.tb_Banner
                                 where banner.Name.StartsWith(find)
                                 group banner by banner.tb_Area.Id into area
                                 select area.Count()).ToList();

                return countList;
            }
        }
        #endregion

        #region IRowCountOperation Members

        public int GetTotalRowCount()
        {
            DataContext context = new DataContext();
            using (context)
            {
                int rowCount = (from banner in context.tb_Banner
                                select banner).Count();

                return rowCount;
            }
        }
        public int GetTotalRowCount(Dictionary<string, string> find)
        {
            DataContext context = new DataContext();
            using (context)
            {
                string findName = find["name"];
                int rowCount = (from banner in context.tb_Banner
                                where banner.Name.StartsWith(findName)
                                select banner).Count();

                return rowCount;
            }
        }
        #endregion

        #region IStateOperation Members

        public void SetActive(int id)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var viewState = (from banner in context.tb_Banner
                                 where banner.Id == id
                                 select banner).FirstOrDefault();

                viewState.tb_StateReference.EntityKey = new EntityKey("DataContext.tb_State", "Id", Convert.ToInt32(State.Active));

                context.SaveChanges();
            }
        }
        public void SetPassive(int id)
        {
            DataContext context = new DataContext();
            using (context)
            {
                var viewState = (from banner in context.tb_Banner
                                 where banner.Id == id
                                 select banner).FirstOrDefault();

                viewState.tb_StateReference.EntityKey = new EntityKey("DataContext.tb_State", "Id", Convert.ToInt32(State.Passive));

                context.SaveChanges();
            }
        }
        #endregion

    }
}
